GtkIconTheme: Support looking up directional variants
authorMatthias Clasen <mclasen@redhat.com>
Wed, 14 May 2014 01:34:49 +0000 (03:34 +0200)
committerBenjamin Otte <otte@redhat.com>
Wed, 14 May 2014 02:28:36 +0000 (04:28 +0200)
Add two new icon lookup flags, GTK_ICON_LOOKUP_DIR_LTR and _RTL,
which tell GtkIconTheme to look for icon variants which have a
-ltr or -rtl suffix. GtkIconHelper adds these lookup flags when
looking up icons.

Note that due to the way this overlaps with symbolic icon lookup,
directional variants of symbolic icons must be called -symbolic-rtl, not
-rtl-symbolic.

https://bugzilla.gnome.org/show_bug.cgi?id=729980

gtk/gtkicontheme.c
gtk/gtkicontheme.h
gtk/gtkstylecontext.c

index 3d3a148f64ae79f854efb49d1c815fe950316ada..58f29135c3cc0bc4c56dad9e8c826cb4d95b5aa6 100644 (file)
@@ -1594,13 +1594,17 @@ symbolic_pixbuf_cache_free (SymbolicPixbufCache *cache)
 static gboolean
 icon_name_is_symbolic (const char *icon_name)
 {
-  return g_str_has_suffix (icon_name, "-symbolic");
+  return g_str_has_suffix (icon_name, "-symbolic")
+      || g_str_has_suffix (icon_name, "-symbolic-ltr")
+      || g_str_has_suffix (icon_name, "-symbolic-rtl");
 }
 
 static gboolean
 icon_uri_is_symbolic (const char *icon_name)
 {
-  return g_str_has_suffix (icon_name, "-symbolic.svg");
+  return g_str_has_suffix (icon_name, "-symbolic.svg")
+      || g_str_has_suffix (icon_name, "-symbolic-ltr.svg")
+      || g_str_has_suffix (icon_name, "-symbolic-rtl.svg");
 }
 
 static GtkIconInfo *
@@ -1806,6 +1810,16 @@ real_choose_icon (GtkIconTheme       *icon_theme,
   return icon_info;
 }
 
+static void
+icon_name_list_add_icon (GPtrArray  *icons,
+                         const char *dir_suffix,
+                         char       *icon_name)
+{
+  if (dir_suffix)
+    g_ptr_array_add (icons, g_strconcat (icon_name, dir_suffix, NULL));
+  g_ptr_array_add (icons, icon_name);
+}
+
 static GtkIconInfo *
 choose_icon (GtkIconTheme       *icon_theme,
              const gchar        *icon_names[],
@@ -1816,8 +1830,16 @@ choose_icon (GtkIconTheme       *icon_theme,
   gboolean has_regular = FALSE, has_symbolic = FALSE;
   GtkIconInfo *icon_info;
   GPtrArray *new_names;
+  const char *dir_suffix;
   guint i;
 
+  if (flags & GTK_ICON_LOOKUP_DIR_LTR)
+    dir_suffix = "-ltr";
+  else if (flags & GTK_ICON_LOOKUP_DIR_RTL)
+    dir_suffix = "-rtl";
+  else
+    dir_suffix = NULL;
+
   for (i = 0; icon_names[i]; i++)
     {
       if (icon_name_is_symbolic (icon_names[i]))
@@ -1832,14 +1854,14 @@ choose_icon (GtkIconTheme       *icon_theme,
       for (i = 0; icon_names[i]; i++)
         {
           if (icon_name_is_symbolic (icon_names[i]))
-            g_ptr_array_add (new_names, g_strndup (icon_names[i], strlen (icon_names[i]) - strlen ("-symbolic")));
+            icon_name_list_add_icon (new_names, dir_suffix, g_strndup (icon_names[i], strlen (icon_names[i]) - strlen ("-symbolic")));
           else
-            g_ptr_array_add (new_names, g_strdup (icon_names[i]));
+            icon_name_list_add_icon (new_names, dir_suffix, g_strdup (icon_names[i]));
         }
       for (i = 0; icon_names[i]; i++)
         {
           if (icon_name_is_symbolic (icon_names[i]))
-            g_ptr_array_add (new_names, g_strdup (icon_names[i]));
+            icon_name_list_add_icon (new_names, dir_suffix, g_strdup (icon_names[i]));
         }
       g_ptr_array_add (new_names, NULL);
 
@@ -1857,14 +1879,31 @@ choose_icon (GtkIconTheme       *icon_theme,
       for (i = 0; icon_names[i]; i++)
         {
           if (!icon_name_is_symbolic (icon_names[i]))
-            g_ptr_array_add (new_names, g_strconcat (icon_names[i], "-symbolic", NULL));
+            icon_name_list_add_icon (new_names, dir_suffix, g_strconcat (icon_names[i], "-symbolic", NULL));
           else
-            g_ptr_array_add (new_names, g_strdup (icon_names[i]));
+            icon_name_list_add_icon (new_names, dir_suffix, g_strdup (icon_names[i]));
         }
       for (i = 0; icon_names[i]; i++)
         {
           if (!icon_name_is_symbolic (icon_names[i]))
-            g_ptr_array_add (new_names, g_strdup (icon_names[i]));
+            icon_name_list_add_icon (new_names, dir_suffix, g_strdup (icon_names[i]));
+        }
+      g_ptr_array_add (new_names, NULL);
+
+      icon_info = real_choose_icon (icon_theme,
+                                    (const gchar **) new_names->pdata,
+                                    size,
+                                    scale,
+                                    flags & ~(GTK_ICON_LOOKUP_FORCE_REGULAR | GTK_ICON_LOOKUP_FORCE_SYMBOLIC));
+
+      g_ptr_array_free (new_names, TRUE);
+    }
+  else if (dir_suffix)
+    {
+      new_names = g_ptr_array_new_with_free_func (g_free);
+      for (i = 0; icon_names[i]; i++)
+        {
+          icon_name_list_add_icon (new_names, dir_suffix, g_strdup (icon_names[i]));
         }
       g_ptr_array_add (new_names, NULL);
 
index c11cfabcf9f6cf5ac29576a6c9b9f3c92f035b8e..662545b694e74e2f965423c6292bb0203ae3c94d 100644 (file)
@@ -117,6 +117,10 @@ struct _GtkIconThemeClass
  *   when symbolic icon names are given. Since 3.14.
  * @GTK_ICON_LOOKUP_FORCE_SYMBOLIC: Try to always load symbolic icons, even
  *   when regular icon names are given. Since 3.14.
+ * @GTK_ICON_LOOKUP_DIR_LTR: Try to load a variant of the icon for left-to-right
+ *   text direction. Since 3.14.
+ * @GTK_ICON_LOOKUP_DIR_RTL: Try to load a variant of the icon for right-to-left
+ *   text direction. Since 3.14.
  * 
  * Used to specify options for gtk_icon_theme_lookup_icon()
  */
@@ -128,7 +132,9 @@ typedef enum
   GTK_ICON_LOOKUP_GENERIC_FALLBACK = 1 << 3,
   GTK_ICON_LOOKUP_FORCE_SIZE       = 1 << 4,
   GTK_ICON_LOOKUP_FORCE_REGULAR    = 1 << 5,
-  GTK_ICON_LOOKUP_FORCE_SYMBOLIC   = 1 << 6
+  GTK_ICON_LOOKUP_FORCE_SYMBOLIC   = 1 << 6,
+  GTK_ICON_LOOKUP_DIR_LTR          = 1 << 7,
+  GTK_ICON_LOOKUP_DIR_RTL          = 1 << 8
 } GtkIconLookupFlags;
 
 /**
index c9b1812a22ad18b0ea84cfa5e16177a824630895..ebdc2435851f73b3d80ea1376dd47647e2638690 100644 (file)
@@ -4682,6 +4682,7 @@ GtkIconLookupFlags
 _gtk_style_context_get_icon_lookup_flags (GtkStyleContext *context)
 {
   GtkCssIconStyle icon_style;
+  GtkIconLookupFlags flags;
 
   g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), 0);
 
@@ -4690,15 +4691,25 @@ _gtk_style_context_get_icon_lookup_flags (GtkStyleContext *context)
   switch (icon_style)
     {
     case GTK_CSS_ICON_STYLE_REGULAR:
-      return GTK_ICON_LOOKUP_FORCE_REGULAR;
+      flags = GTK_ICON_LOOKUP_FORCE_REGULAR;
+      break;
     case GTK_CSS_ICON_STYLE_SYMBOLIC:
-      return GTK_ICON_LOOKUP_FORCE_SYMBOLIC;
+      flags = GTK_ICON_LOOKUP_FORCE_SYMBOLIC;
+      break;
     case GTK_CSS_ICON_STYLE_REQUESTED:
-      return 0;
+      flags = 0;
+      break;
     default:
       g_assert_not_reached ();
       return 0;
     }
+
+  if (context->priv->info->state_flags & GTK_STATE_FLAG_DIR_LTR)
+    flags |= GTK_ICON_LOOKUP_DIR_LTR;
+  else if (context->priv->info->state_flags & GTK_STATE_FLAG_DIR_RTL)
+    flags |= GTK_ICON_LOOKUP_DIR_RTL;
+
+  return flags;
 }
 
 static AtkAttributeSet *